package com.wfh.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wfh.constant.RedisLuaScriptConstant;
import com.wfh.listener.thumb.msg.ThumbEvent;
import com.wfh.manager.cache.CacheManager;
import com.wfh.mapper.ThumbMapper;
import com.wfh.model.dto.thumb.DoThumbRequest;
import com.wfh.model.entity.Thumb;
import com.wfh.model.entity.User;
import com.wfh.model.enums.LuaStatusEnum;
import com.wfh.config.RabbitMQConfig;
import com.wfh.service.BlogService;
import com.wfh.service.ThumbService;
import com.wfh.service.UserService;
import com.wfh.utils.RedisKeyUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import java.time.LocalDateTime;
import java.util.List;

/**
* @author lenovo
* @description 针对表【thumb】的数据库操作Service实现
* @createDate 2025-04-18 17:26:50
*/
@Service("thumbService")
@RequiredArgsConstructor
@Slf4j
public class ThumbServiceMQImpl extends ServiceImpl<ThumbMapper, Thumb>
    implements ThumbService {

    private final UserService userService;

    private final BlogService blogService;

    private final TransactionTemplate transactionTemplate;

    private final RedisTemplate<String, Object> redisTemplate;

    private final CacheManager cacheManager;

    private final RabbitTemplate rabbitTemplate;

    @Resource
    private RedissonClient redissonClient;

    /**
     * 点赞
     *
     * @param doThumbRequest
     * @param request
     * @return
     */
    @Override
    public Boolean doThumb(DoThumbRequest doThumbRequest, HttpServletRequest request) {
        if (doThumbRequest == null || doThumbRequest.getBlogId() == null) {
            throw new RuntimeException("请求参数错误");
        }
        User loginUser = userService.getLoginUser(request);
        Long loginUserId = loginUser.getId();
        Long blogId = doThumbRequest.getBlogId();
        String userThumbKey = RedisKeyUtil.getUserThumbKey(loginUserId);

        // 执行Lua脚本，点赞存入redis
        Long res = redisTemplate.execute(RedisLuaScriptConstant.THUMB_SCRIPT_MQ,
                List.of(userThumbKey), blogId);
        if (LuaStatusEnum.FAIL.getValue() == res){
            throw new RuntimeException("用户已经点赞");
        }
        ThumbEvent thumbEvent = ThumbEvent.builder()
                .blogId(blogId)
                .userId(loginUserId)
                .type(ThumbEvent.EventType.INCR)
                .eventTime(LocalDateTime.now())
                .build();
        // 发送消息到RabbitMQ消息队列
        try {
            rabbitTemplate.convertAndSend(RabbitMQConfig.THUMB_EXCHANGE, RabbitMQConfig.THUMB_ROUTING_KEY, thumbEvent);
        } catch (Exception ex) {
            redisTemplate.opsForHash().delete(userThumbKey, blogId.toString());
            log.error("点赞事件发送失败：userId={}， blogId={}, Ex={}", loginUserId, blogId, ex.getMessage());
        }
       return true;
    }

    /**
     * 取消点赞
     *
     * @param doThumbRequest
     * @param request
     * @return
     */
    @Override
    public Boolean undoThumb(DoThumbRequest doThumbRequest, HttpServletRequest request) {
        if (doThumbRequest == null || doThumbRequest.getBlogId() == null) {
            throw new RuntimeException("请求参数错误");
        }
        User loginUser = userService.getLoginUser(request);
        Long loginUserId = loginUser.getId();
        Long bolgId = doThumbRequest.getBlogId();
        String userThumbKey = RedisKeyUtil.getUserThumbKey(loginUserId);
        // 执行lua脚本，点赞记录将会从redis中删除
        Long res = redisTemplate.execute(RedisLuaScriptConstant.UNTHUMB_SCRIPT_MQ,
                List.of(userThumbKey),
                bolgId);
        if (LuaStatusEnum.FAIL.getValue() == res){
            throw new RuntimeException("用户还没有点赞");
        }
        ThumbEvent thumbEvent = ThumbEvent.builder()
                .blogId(bolgId)
                .userId(loginUserId)
                .type(ThumbEvent.EventType.DECR)
                .eventTime(LocalDateTime.now())
                .build();
        // 发送到消息队列异步处理
        try {
            rabbitTemplate.convertAndSend(RabbitMQConfig.THUMB_EXCHANGE, RabbitMQConfig.THUMB_ROUTING_KEY, thumbEvent);
        } catch (Exception ex) {
            redisTemplate.opsForHash().put(userThumbKey, bolgId.toString(), true);
            log.error("取消点赞事件发送失败：userId={}， blogId={}, Ex={}", loginUserId, bolgId, ex.getMessage());
        }
       return true;
    }

    /**
     * 是否已经点赞
     * @param blogId
     * @param userId
     * @return
     */
    @Override
    public Boolean hasThumb(Long blogId, Long userId) {
      return redisTemplate.opsForHash().hasKey(RedisKeyUtil.getUserThumbKey(userId), blogId.toString());
    }
}




